package
{
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import systems.Backgrounds;
	import systems.Collisions;
	import systems.Enemies;
	import systems.States;
	import systems.events.EnemyEvent;
	import systems.Input;
	import systems.EventChannel;
	import systems.events.BulletEvent;
	import systems.events.ShipEvent;
	
	/**
	 * @author Humberto Anjos
	 */
	public class Main extends MovieClip
	{
		var _container:DisplayObjectContainer = new MovieClip()
		
		var _input:Input
		var _backgrounds:Backgrounds
		var _enemies:Enemies
		var _world:GameWorld
		var _collisions:Collisions
		
		public function Main()
		{
			_input = new Input(this)
			_backgrounds = new Backgrounds(this)
			_enemies = new Enemies(this)
			_world = new GameWorld()
			_collisions = new Collisions(this)
			
			drawMain()
		}
		
		private function drawMain():void
		{
			EventChannel.INSTANCE.addEventListener(
				BulletEvent.BULLET_CREATED, onBulletCreated, false, 0, true)
			EventChannel.INSTANCE.addEventListener(
				BulletEvent.BULLET_DESTROYED, onBulletDestroyed,  false, 0, true)
			EventChannel.INSTANCE.addEventListener(
				EnemyEvent.ENEMY_CREATED, onEnemyCreated, false, 0, true)
			EventChannel.INSTANCE.addEventListener(
				EnemyEvent.ENEMY_DESTROYED, onEnemyDestroyed, false, 0, true)
			EventChannel.INSTANCE.addEventListener(
				ShipEvent.SHIP_CREATED, onShipCreated, false, 0, true)
			EventChannel.INSTANCE.addEventListener(
				ShipEvent.SHIP_DESTROYED, onShipDestroyed, false, 0, true)
				
			start()
		}
		
		private function start():void
		{
			//_container = new MovieClip()
			
			_input.start()
			_world.start()
			
			stage.addEventListener(Event.ENTER_FRAME, update, false, 0, true)
			
			drawScreen();
		}
		
		private function update(e:Event):void 
		{
			checkInput()
			
			_world.update()
			_enemies.update()
			_collisions.update()
		}
		
		private function checkInput() 
		{ 
			if (_input.active.left) {
				_world.ship.move(Ship.LEFT)
			}
			
			if (_input.active.right) {
				_world.ship.move(Ship.RIGHT)
			}
			
			if (_input.active.up) {
				_world.ship.move(Ship.UP)
			}
			
			if (_input.active.down) {
				_world.ship.move(Ship.DOWN)
			}
			
			if (_input.active.shoot) {
				_world.ship.shoot()
			}
		}
		
		private function drawScreen():void
		{
			addChild(_container) // must happen first!
			
			_backgrounds.draw()
			_world.newShip(States.PURPLE, 300, 300)
		}
		
		private function onBulletCreated(e:BulletEvent) 
		{ 
			trace("onBulletCreated", e); 
			_container.addChild(e.bullet) 
		}
		
		private function onBulletDestroyed(e:BulletEvent) 
		{ 
			trace("onBulletDestroyed", e)
			_container.removeChild(e.bullet) 
		}
		
		private function onEnemyCreated(e:EnemyEvent) 
		{ 
			trace("onEnemyCreated", e)
			_container.addChild(e.enemy) 
		}
		
		private function onEnemyDestroyed(e:EnemyEvent) { 
			trace("onEnemyDestroyed", e)
			_container.removeChild(e.enemy) 
		}
		
		private function onShipCreated(e:ShipEvent) 
		{ 
			trace("onShipCreated", e) 
			_container.addChild(e.ship) 
			_input.addEventListener(e.ship.changeStateTo)
		}
		
		private function onShipDestroyed(e:ShipEvent) { 
			trace("onShipDestroyed", e)
			_container.removeChild(e.ship)
			
			stage.removeEventListener(Event.ENTER_FRAME, update)
			
			_input.clear()
			_world.clear()
			
			removeChild(_container)
			
			stage.addEventListener(MouseEvent.CLICK, callStart, false, 0, true)
		}
		
		private function callStart (e:MouseEvent) 
		{ 
			stage.removeEventListener(MouseEvent.CLICK, callStart)
			start() 
		}
		
		public function get container():DisplayObjectContainer { return _container; }
		public function get world():GameWorld { return _world; }
	}
}
